package cn.edu.lcu.cs.javaprogramming.annotations;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;

/**
 * JTableColumn注解的处理器
 *
 * @author ling
 */
public class JTableColumnProcessor {

    /**
     * 将类中加注解的字段上定义的列名取出。
     *
     * @param clazz
     * @return
     */
    public static Object[] getColumnNames(Class<?> clazz) {
        // 获取所有field
        Field[] fields = clazz.getDeclaredFields();
        return Arrays.stream(fields)
                // 过滤掉没有注解的Field
                .filter(f -> f.isAnnotationPresent(JTableColumn.class))
                // 将Field转换为Column Annotation
                .map(f -> f.getAnnotation(JTableColumn.class))
                // 按照注解的index排序
                .sorted((c1, c2) -> c1.index() - c2.index())
                // 将注解转换为列名
                .map(JTableColumn::name)
                .toArray();
    }

    /**
     * 将对象中加注解的字段值取出，形成TableModel一行数据。
     *
     * @param object
     * @return
     */
    public static Object[] getRow(Object object) {
        Field[] fields = object.getClass().getDeclaredFields();
        return Arrays.stream(fields) //
                // 过滤掉没有注解的Field
                .filter(f -> f.isAnnotationPresent(JTableColumn.class))
                // 按照index排序
                .sorted((f1, f2) -> f1.getAnnotation(JTableColumn.class).index()
                        - f2.getAnnotation(JTableColumn.class).index())
                // field转换为字段值
                .map(f -> {
                    try {
                        // private 字段也可访问了
                        f.setAccessible(true);
                        return f.get(object);
                    } catch (IllegalArgumentException | IllegalAccessException e) {
                        e.printStackTrace();
                        return null;
                    }
                }).toArray();
    }

    /**
     * 将列表中各个对象上加注解的字段值取出，形成TableModel的数据行列矩阵。
     *
     * @param collection
     * @return
     */
    public static Object[][] getRows(Collection collection) {
        if (collection != null && !collection.isEmpty()) {
            Object[][] rows = new Object[collection.size()][];
            int i = 0;
            for (Object item : collection) {
                rows[i++] = JTableColumnProcessor.getRow(item);
            }
            return rows;
        } else {
            return null;
        }
    }
}
